import {
  CesiumPoint,
  CesiumPolyline,
  CesiumPolygon
} from "./Graphic";
import utils from "@/js/utils";
import pointIcon1 from "@/assets/images/1.png";
import pointIcon2 from "@/assets/images/2.png";
import pointIcon3 from "@/assets/images/3.png";
import pointIcon4 from "@/assets/images/4.png";
import pointIcon5 from "@/assets/images/5.png";
import pointIcon6 from "@/assets/images/6.png";
import pointIcon7 from "@/assets/images/7.png";
import pointIcon8 from "@/assets/images/8.png";
import pointIcon9 from "@/assets/images/9.png";
import pointIcon10 from "@/assets/images/10.png";
import pointIconDefault from "@/assets/images/default.png";
import {
  CVT
} from "@/js/utils";
import GraphicType from "./GraphicType";
import {
  saveAs
} from "file-saver";
const console = window.console;
const LEFT_CLICK = Cesium.ScreenSpaceEventType.LEFT_CLICK;
const RIGHT_CLICK = Cesium.ScreenSpaceEventType.RIGHT_CLICK;
const MOUSE_MOVE = Cesium.ScreenSpaceEventType.MOUSE_MOVE;
const MOUSE_DOWN = Cesium.ScreenSpaceEventType.LEFT_DOWN;
const MOUSE_UP = Cesium.ScreenSpaceEventType.LEFT_UP;
const iconOb = {
  1: pointIcon1,
  2: pointIcon2,
  3: pointIcon3,
  4: pointIcon4,
  5: pointIcon5,
  6: pointIcon6,
  7: pointIcon7,
  8: pointIcon8,
  9: pointIcon9,
  10: pointIcon10,
  default: pointIconDefault,
};
class GraphicManager {
  /**
   * 鼠标交互绘制线和多边形
   * @param {Viewer}} viewer Cesium Viewer
   * @param {*} options 预留参数，目前不需要关注
   */
  constructor(viewer, options = {}) {
    if (viewer instanceof Cesium.Viewer === false) {
      throw new Error("viewer不是一个有效的Cesium Viewer");
    }

    this.viewer = viewer;
    this.options = options;
    /*heightReference 定义几何图形的高程基准
     *CLAMP_TO_GROUND:依附地形
     *CLAMP_TO_MODEL:依附模型
     *NONE:空间线
     */
    this._heightReference = "CLAMP_TO_GROUND";
    this._material = undefined;
    this._style = {};

    this.graphicId = undefined;
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
    this.graphicType = undefined;
    this.positions = [];
    this.tip = new utils.CursorTip("");
    this.tip.visible = false;
    this.mode = "ready";
    this.dragging = false;
    // this.init()
    // this.addEventListener()
    //当前正在编辑的graphic
    this.editManager = undefined;
    this.selectedNodeIndex = -1;
    //Graphic集合
    this.manager = new Map();
    // const self = this;
    //TODO 解决不了删除后的继续编辑状态故而不允许删除
    // document.onkeydown = function (event) {
    //   if (self.mode !== "edit") return;

    //   const e = event || window.event || arguments.callee.caller.arguments[0];
    //   //增加mac del删除的键
    //   if (e && (e.keyCode === 46 || e.key === "Backspace")) {
    //     // 按 delete
    //     if (self.selectedNodeIndex > -1 && self.editManager) {
    //       self.editManager.dropNode(self.selectedNodeIndex);
    //       self.highlightedNode(undefined, self.editManager.nodeGraphic);
    //       self.selectedNodeIndex = -1;
    //     } else if (self.editManager) {
    //       self.editManager.destroy();
    //       self.manager.delete(self.editManager.id);
    //       self.mode = "end";

    //       self.tip.visible = false;
    //       const evt = new CustomEvent("deleteEvent", {
    //         detail: {
    //           mid: self.editManager ? self.editManager.mid : undefined,
    //         },
    //       });
    //       document.dispatchEvent(evt);
    //       self.editManager = undefined;
    //       // self.removeEventListener();
    //     }
    //   }
    // };
    // this.tip.style.display='none'
  }
  get heightReference() {
    return this._heightReference;
  }
  set heightReference(h) {
    this._heightReference = h;
    if (this.editManager) {
      this.editManager.heightReference = h;
      if (this.editManager.type === "POLYLINE") {
        this.editManager.graphic.polyline.clampToGround = /.*GROUND.*/.test(h);
        this.editManager.options.polyline.clampToGround = /.*GROUND.*/.test(h);
      } else if (this.editManager.type === "POLYGON") {
        const graphic = this.editManager.graphic;
        const options = this.editManager.options;
        if (/.*GROUND.*/.test(h)) {
          graphic.polygon.perPositionHeight = false;
          if (this.editManager.outline) {
            this.editManager.outlineGraphic.graphic.polyline.clampToGround = true;
          } // polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
          // options.polygon.heightReference= Cesium.HeightReference.CLAMP_TO_GROUND
          options.polygon.perPositionHeight = false;
        } else {
          graphic.polygon.perPositionHeight = true;
          if (this.editManager.outline) {
            this.editManager.outlineGraphic.graphic.polyline.clampToGround = false;
          }
          // polygon.heightReference = Cesium.HeightReference.RELATIVE_TO_GROUND
          // options.polygon.heightReference= Cesium.HeightReference.RELATIVE_TO_GROUND
          options.polygon.perPositionHeight = true;
        }
      }
    }
  }
  get material() {
    return this._material;
  }
  set material(v) {
    this._material = v;
    if (this.editManager) {
      if (this.editManager.type === "POLYLINE") {
        this.editManager.graphic.polyline.material = this._material;
        this.editManager.options.polyline.material = this._material;
      } else if (this.editManager.type === "POLYGON") {
        this.editManager.graphic.polygon.material = this._material;
        this.editManager.options.polygon.material = this._material;
      }
    }
  }
  get style() {
    return this._style;
  }
  set style(option) {
    this._style = option;
    if (!this.editManager) {
      return;
    }
    const keys = Object.keys(option);
    for (let key of keys) {
      if (this.editManager.type === "POLYLINE") {
        this.editManager.graphic.polyline[key] = option[key];
        this.editManager.options.polyline[key] = option[key];
      } else if (this.editManager.type === "POLYGON") {
        if (key !== "outline") {
          this.editManager.graphic.polygon[key] = option[key];
        }

        this.editManager.options.polygon[key] = option[key];
      }
    }
    if (this.editManager.type === "POLYGON") {
      this.editManager.outlineStyle = option;
    }
  }

  /**
   *
   * @param {Object} options 定义一个CesiumPolyline
   */
  createPolyline(options = CesiumPolyline.defaultStyle) {
    this.graphicType = GraphicType.POLYLINE;
    const id = this.generateId();
    options.positions = this.positions;
    if (/.*GROUND.*/.test(this._heightReference)) {
      options.clampToGround = true;
    } else {
      options.clampToGround = false;
    }
    options.material = this.material || options.material;
    options.width = this.style.width || options.width;
    const manager = new CesiumPolyline(this.viewer, options);
    this.tip.updateText("右击结束");
    this.tip.visible = true;
    manager.mid = id;
    // manager.id = id
    // manager.mname = '未命名';
    manager.heightReference = this.heightReference;
    this.manager.set(id, manager);
    this.graphicId = id;
    this.editManager = manager;
    const evt = new CustomEvent("addEvent", {
      detail: {
        mid: manager.mid,
        mtype: manager.mtype,
        mname: manager.mname,
      },
    });
    document.dispatchEvent(evt);
    const self = this;
    this.handler.setInputAction((e) => {
      self.tip && self.tip.updatePosition(e.endPosition);
    }, MOUSE_MOVE);
    this.addEventListener();
    return manager;
  }

  /**
   *
   * @param {Object} options 定义一个CesiumPolygon
   */
  createPolygon(options = CesiumPolygon.defaultStyle) {
    this.graphicType = GraphicType.POLYGON;
    const id = this.generateId();
    this.graphicId = id;
    options.positions = this.positions;
    if (/.*GROUND.*/.test(this._heightReference)) {
      options.perPositionHeight = false;
      // options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
    } else {
      options.perPositionHeight = true;
      // options.heightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
      // options.height = 0
    }

    options.material = this.material || options.material;
    options.outlineWidth = this.style.outlineWidth || options.outlineWidth;
    options.outlineColor = this.style.outlineColor || options.outlineColor;
    const manager = new CesiumPolygon(this.viewer, options);
    manager.mid = id;
    // manager.id = id;
    // manager.mname = '未命名';
    manager.heightReference = this.heightReference;
    this.tip.visible = true;
    this.tip.updateText("点击图层开始");
    this.manager.set(id, manager);
    this.editManager = manager;
    const evt = new CustomEvent("addEvent", {
      detail: {
        mid: manager.mid,
        mtype: manager.mtype,
        mname: manager.mname,
      },
    });
    document.dispatchEvent(evt);
    const self = this;
    this.handler.setInputAction((e) => {
      self.tip && self.tip.updatePosition(e.endPosition);
    }, MOUSE_MOVE);
    this.addEventListener();
    return manager;
  }
  generateId() {
    return (
      (Math.random() * 10000000).toString(16).substr(0, 4) +
      "-" +
      new Date().getTime() +
      "-" +
      Math.random().toString().substr(2, 5)
    );
  }
  isKnownGraphic(pickedObj) {
    if (
      Cesium.defined(pickedObj) &&
      pickedObj.id instanceof Cesium.Entity &&
      (pickedObj.id.mtype === GraphicType.POLYLINE ||
        pickedObj.id.mtype === GraphicType.POLYGON ||
        pickedObj.id.mtype === GraphicType.POINT)
    ) {
      return true;
    }
    return false;
  }
  /**
   * 将当前选中的点设为高亮
   * @param {Cartesian3} node
   * @param {CesiumPoint} cp
   */
  highlightedNode(node, cp) {
    const soption = CesiumPoint.selectedStyle;
    const doption = CesiumPoint.defaultStyle;
    for (let n of cp.graphic) {
      if (n === node) {
        CesiumPoint.setStyle(n, soption);
      } else {
        CesiumPoint.setStyle(n, doption);
      }
    }
  }
  addEventListener() {
    const self = this;
    const viewer = this.viewer;
    const clickHandler = function (e) {
      self.tip.updateText("右击结束");
      //编辑要素
      if (self.mode === "edit") {
        if (!self.editManager) {
          self.removeEventListener();
          return;
        }
        const nodeGraphic =
          self.editManager.nodeGraphic ||
          self.editManager.outlineGraphic.nodeGraphic;
        const pickedObjs = viewer.scene.drillPick(e.position);
        let known = false,
          pickedObj = undefined;
        for (let obj of pickedObjs) {
          known = self.isKnownGraphic(obj);
          if (known && obj.id.mtype === GraphicType.POINT) {
            pickedObj = obj;
            //再事件监听之前移除上次的监听
            self.handler.removeInputAction(MOUSE_DOWN);
            self.handler.removeInputAction(MOUSE_MOVE);
            self.handler.setInputAction(mouseDownHandler, MOUSE_DOWN);
            self.handler.setInputAction(mouseMoveHandler, MOUSE_MOVE);
            break;
          }
        }
        // const pickedPosition=CVT.pixel2Cartesian(e.position,viewer)

        if (pickedObj && known) {
          if (pickedObj.id.mtype === GraphicType.POINT) {
            self.selectedNodeIndex = nodeGraphic.contain(pickedObj.id);
            if (self.selectedNodeIndex !== -1) {
              self.highlightedNode(pickedObj.id, nodeGraphic);
            }
          } else {
            self.highlightedNode(pickedObj.id, self.editManager.nodeGraphic);
            self.selectedNodeIndex = -1;
          }
        } else {
          self.editManager && self.editManager.stopEdit();
          // self.handler.removeInputAction(MOUSE_MOVE);
          self.removeEventListener();
          self.mode = "end";
          self.selectedNodeIndex = -1;
          self.editManager = undefined;
          self.tip.visible = false;
          const evt = new CustomEvent("stopEdit");
          document.dispatchEvent(evt);


          //结束的时候重新画点
          let id = self.graphicId
          // let entityId = id + "__entitys__";
          const __ma_ = self.manager.get(id)
          // entityArr.length && entityArr.forEach((entity) => {
          //   viewer.entities.remove(entity);
          // });
          self.clearEntity(id)
          //重新画点
          viewer.scene.screenSpaceCameraController.enableRotate = true;
          // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
          viewer.scene.screenSpaceCameraController.enableTranslate = true;
          // __ma_.positions.forEach((cartesian, index) => {
          //   let index_ = index + 1
          //   let iconStr = index_ >= 10 ? "default" : index_;
          //   let videoEntity = viewer.entities.add({
          //     // id: id,
          //     position: cartesian,
          //     billboard: {
          //       // 图像地址，URI或Canvas的属性
          //       image: iconOb[iconStr],
          //       pixelOffset: new Cesium.Cartesian2(0, 0),
          //       //不被遮挡覆盖
          //       eyeOffset: new Cesium.Cartesian3(0, 0, -10000),
          //       verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          //       horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          //     },
          //   });
          //   videoEntity.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND; //图标的位置被固定在地形上
          //   let entityArr = self.manager.has(entityId) ?
          //     self.manager.get(entityId) : [];
          //   entityArr.push(videoEntity);
          //   self.manager.set(entityId, entityArr);
          // })
          self.tip.visible = false;
          //TODO 处理返回的数据
          self.options.vm.finishEvent(__ma_);
        }
        return;
      }
      //非法的要素类型
      if (
        self.graphicType != GraphicType.POLYLINE &&
        self.graphicType != GraphicType.POLYGON
      ) {
        return;
      }
      let cartesian = CVT.pixel2Cartesian(e.position, self.viewer);
      if (/.*MODEL.*/.test(self._heightReference)) {
        if (!viewer.scene.pickPositionSupported) {
          console.log("This browser does not support pickPosition.");
          return;
        }
        cartesian = viewer.scene.pickPosition(e.position);
      }
      //添加第一个点后再监听鼠标移动事件，绘绘完成后移除监听，以免不必要的事件监听
      let __p = self.manager.get(self.graphicId)
      if (__p && __p.positions.length === 0) {
        self.handler.removeInputAction(MOUSE_MOVE);
        self.handler.setInputAction(mouseMoveHandler, MOUSE_MOVE);
      }
      if (Cesium.defined(cartesian) && self.manager.has(self.graphicId)) {
        let isGeoFlag = self.editManager.type === "POLYGON";
        //TODO 判断是否存在限制点的个数，要是有就提示
        let limit = !isGeoFlag ?
          self.options.polylineMaxPointNum || 0 :
          self.options.polygonMaxPointNum || 0;
        let checkLimit = limit
        if (isGeoFlag) {
          checkLimit += 1;
        }
        let hasCount = self.positions.length || 0;
        //面数量加1了
        if (limit && hasCount === checkLimit) {
          self.tip.updateText(
            `${!isGeoFlag ? "线" : "区域"}标注最多${
              isGeoFlag ? checkLimit - 1 : checkLimit
            }个点、右击结束`
          );
          return false;
        }
        self.manager.get(self.graphicId).addNode(cartesian);

        let iconStr = hasCount >= 10 ? "default" : hasCount + 1;
        //面的特殊处理
        if (isGeoFlag) {
          iconStr = !hasCount ? 1 : hasCount;
        }
        //增加点
        let videoEntity = viewer.entities.add({
          // id: id,
          position: cartesian,
          billboard: {
            // 图像地址，URI或Canvas的属性
            image: iconOb[iconStr],
            pixelOffset: new Cesium.Cartesian2(0, 0),
            //不被遮挡覆盖
            eyeOffset: new Cesium.Cartesian3(0, 0, -10000),
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
          },
        });
        videoEntity.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND; //图标的位置被固定在地形上
        let entityId = self.graphicId + "__entitys__";

        let entityArr = self.manager.has(entityId) ?
          self.manager.get(entityId) : [];
        entityArr.push(videoEntity);
        self.manager.set(entityId, entityArr);
      }
      self.mode = "create";
    };
    //TODO 右击结束的时候限制
    const rightHandler = function () {
      let id = self.graphicId
      const manager = self.manager.get(id);

      if (self.mode === "create" && manager) {
        //判断要是点不够的话不让结束
        let isGeoFlag = self.editManager.type === "POLYGON";
        //TODO 判断是否存在限制点的个数，要是有就提示
        let limit = !isGeoFlag ?
          self.options.polylineMaxPointNum || 0 :
          self.options.polygonMaxPointNum || 0;
        let hasCount = self.positions.length || 0;
        if (!isGeoFlag && hasCount < 2) {
          self.tip.updateText(`线标注至少2个点`);
          return false;
        }
        //面至少需要3个点，面的要多一个鼠标hover会加一个点
        if (isGeoFlag && hasCount < 4) {
          self.tip.updateText(`区域标注至少3个点`);
          return false;
        }
        if (isGeoFlag && limit && hasCount !== limit + 1) {
          self.tip.updateText(`区域标注需要${limit}个点`);
          return false;
        }
        //这个是应为面最后会多出一个相同的点，删掉
        if (isGeoFlag) {
          //
          manager.popNode();
          //线也会多一个
          // manager.outlineGraphic && (manager.outlineGraphic.popNode())
        }
        manager.stopEdit();
        self.graphicType = undefined;
        self.graphicId = undefined;
        self.positions = [];
        self.mode = "end";
        self.tip.visible = false;
        self.editManager = undefined;
        const evt = new CustomEvent("stopEdit");
        document.dispatchEvent(evt);
      } else if (self.mode === "ready") {
        self.cancel();
      } else if (self.mode === "edit") {
        self.editManager && self.editManager.stopEdit();
        // self.handler.removeInputAction(MOUSE_MOVE);
        self.removeEventListener();
        self.mode = "end";
        self.selectedNodeIndex = -1;
        // self.editManager = undefined
        // self.tip.visible = false;
      }
      // self.handler.removeInputAction(MOUSE_MOVE);
      self.tip.visible = false;
      const evt = new CustomEvent("stopEdit");
      document.dispatchEvent(evt);
      self.removeEventListener();
      //结束的时候重新画点
      self.clearEntity(id)
      viewer.scene.screenSpaceCameraController.enableRotate = true;
      // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
      viewer.scene.screenSpaceCameraController.enableTranslate = true;
      //重新画点 TODO 绘制结束去掉点

      // manager.positions.forEach((cartesian, index) => {
      //   let index_ = index + 1
      //   let iconStr = index_ >= 10 ? "default" : index_;
      //   let videoEntity = viewer.entities.add({
      //     // id: id,
      //     position: cartesian,
      //     billboard: {
      //       // 图像地址，URI或Canvas的属性
      //       image: iconOb[iconStr],
      //       pixelOffset: new Cesium.Cartesian2(0, 0),
      //       //不被遮挡覆盖
      //       eyeOffset: new Cesium.Cartesian3(0, 0, -10000),
      //       verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      //       horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      //     },
      //   });
      //   videoEntity.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND; //图标的位置被固定在地形上
      //   let entityArr = self.manager.has(entityId) ?
      //     self.manager.get(entityId) : [];
      //   entityArr.push(videoEntity);
      //   self.manager.set(entityId, entityArr);
      // })
      //TODO 处理返回的数据
      self.options.vm.finishEvent(manager);
    };

    const mouseMoveHandler = function (e) {
      let cartesian = CVT.pixel2Cartesian(e.endPosition, self.viewer);
      //3D模式
      if (/.*MODEL.*/.test(self._heightReference)) {
        if (!viewer.scene.pickPositionSupported) {
          console.log("This browser does not support pickPosition.");
          return;
        }
        cartesian = viewer.scene.pickPosition(e.endPosition);
      }
      if (!Cesium.defined(cartesian)) {
        return;
      }
      self.tip.updatePosition(e.endPosition);
      //是多边形的则放开，折现的不允许
      self.tip.updateText("右击结束");
      if (self.mode === "create" && self.editManager.type === "POLYGON") {
        let isGeoFlag = self.editManager.type === "POLYGON";
        //TODO 判断是否存在限制点的个数，要是有就提示
        let limit = !isGeoFlag ?
          self.options.polylineMaxPointNum || 0 :
          self.options.polygonMaxPointNum || 0;
        let checkLimit = limit
        if (isGeoFlag) {
          checkLimit += 1;
        }
        let hasCount = self.positions.length || 0;
        if (limit && hasCount === checkLimit) {
          self.tip.updateText(
            `${!isGeoFlag ? "线" : "区域"}标注最多${
              isGeoFlag ? checkLimit - 1 : checkLimit
            }个点、右击结束`
          );
          return false;
        }
        self.tip.updateText("继续点击图层、右击结束");
        //如果当前是create模式，创建辅助线
        if (self.positions.length > 1) {
          self.manager.get(self.graphicId).popNode();
        }
        //添加临时节点
        //再添加第一个节点前，不拾取鼠标移动的坐标
        if (self.positions.length > 0) {
          // self.positions.push(cartesian);
          self.manager.get(self.graphicId).addNode(cartesian);
        }
      }

      if (self.mode == "edit" && self.dragging) {
        self.tip.updateText("点击红色节点，可以拖动编辑");
        if (self.selectedNodeIndex !== -1) {
          self.editManager.updateNode(self.selectedNodeIndex, cartesian);
        }
      }
    };
    const mouseDownHandler = function (e) {
      self.handler.setInputAction(mouseUpHandler, MOUSE_UP);
      const objs = viewer.scene.drillPick(e.position);
      let isCesiumPoint = false;
      for (let obj of objs) {
        if (CesiumPoint.isCesiumPoint(obj)) {
          isCesiumPoint = true;
        }
      }
      if (isCesiumPoint == false) {
        return;
      }
      if (self.mode === "edit" && self.selectedNodeIndex != -1) {
        self.dragging = true;
        //2D模式下禁用拖动
        let isMode2 = viewer._sceneModePicker._viewModel.sceneMode === 2
        viewer.scene.screenSpaceCameraController.enableRotate = false;
        // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
        viewer.scene.screenSpaceCameraController.enableTranslate = !isMode2;
      }
    };
    const mouseUpHandler = function () {
      self.dragging = false;
      viewer.scene.screenSpaceCameraController.enableRotate = true;

      self.handler.removeInputAction(MOUSE_UP);
      // self.handler.removeInputAction(MOUSE_DOWN);
    };
    this.handler.setInputAction(clickHandler, LEFT_CLICK);
    this.handler.setInputAction(rightHandler, RIGHT_CLICK);
  }
  rename(id, name) {
    const graphic = this.manager.get(id);
    if (Cesium.defined(graphic)) {
      graphic.mname = name;
    }
  }
  has(id) {
    if (this.manager) {
      return this.manager.has(id);
    }
    return false;
  }
  get(id) {
    if (this.has(id)) {
      return this.manager.get(id);
    }
  }
  /**
   * 当图形处于ready状态时，不想画了
   */
  cancel() {
    let id = this.graphicId
    const manager = this.manager.get(id);
    manager && manager.stopEdit();
    manager && manager.destroy();
    this.graphicType = undefined;
    this.graphicId = undefined;
    this.positions = [];
    this.mode = "end";
    this.tip.visible = false;
    this.editManager = undefined;
    this.clearEntity(id)
  }
  select(type, id, status) {
    if (Cesium.defined(id)) {
      const manager = this.manager.get(id);
      if (manager) {
        manager.show = status;
        //是面的处理一下线
        if (manager.type === 'POLYGON') {
          manager.outlineGraphic && (manager.outlineGraphic.show = status)
        }
        //编辑状态的点
        if (manager.nodeGraphic && manager.nodeGraphic.graphic) {
          for (let v of manager.nodeGraphic.graphic) {
            v.show = status;
          }
        }
        if (manager.nodeGraphic && manager.nodeGraphic.graphic) {
          manager.nodeGraphic.graphic.show = status
        }
      }
    }
    if (Cesium.defined(type)) {
      const values = this.manager.values();
      for (let v of values) {
        if (v.mtype === type) {
          v.show = status;
        }
      }
    }
    //获取entity
    this.visibleEntity(id, status)

  }
  /**
   * 1 图标问题
   * 2 点击编辑后是否可以删除，要是允许删除 应当重启绘制
   * 
   * 3 一个绘制模式下只能存在一个编辑状态，别的清空 掉，点击两下编辑直接结束
   * @param {*} id
   */
  edit(id) {
    const self = this;
    self.editManager && self.editManager.stopEdit();
    // self.handler.removeInputAction(MOUSE_MOVE);
    self.removeEventListener();
    self.mode = "end";
    self.selectedNodeIndex = -1;
    self.editManager = undefined;
    self.tip.visible = false;
    const evt = new CustomEvent("stopEdit");
    document.dispatchEvent(evt);
    const manager = self.manager.get(id);
    //编辑强制显示
    manager.outlineGraphic && (manager.outlineGraphic.show = true)
    manager.show = true
    if (manager.type === "POLYGON") {
      //导入的逻辑中补了一个点，编辑的时候干掉一个
      if (manager.outlineGraphic.positions.length === manager.positions.length) {
        // let limit = self.options.polygonMaxPointNum || 0;
        //TODO 导入的会少根线
        manager.positions.pop()
      }
    }
    //编辑的时候清除entity
    this.clearEntity(id)
    this.handler.setInputAction((e) => {
      self.tip.updatePosition(e.endPosition);
    }, MOUSE_MOVE);
    self.graphicId = id;
    if (Cesium.defined(manager)) {
      // manager.zoomTo()
      self.mode = "edit";
      manager.startEdit();
      self.tip.visible = true;
      self.tip.updateText("点击红色节点，可以拖动编辑");
      // self.tip.updateText("拖动节点编辑，按del删除.");
      self.editManager = manager;

      const evt = new CustomEvent("startEdit", {
        detail: {
          graphicType: self.editManager.type,
          material: self.editManager.material,
          width: self.editManager.width,
          outline: self.editManager.outline,
          outlineColor: self.editManager.outlineColor,
          outlineWidth: self.editManager.outlineWidth,
          heightReference: self.editManager.heightReference,
        },
      });
      document.dispatchEvent(evt);
      self.addEventListener();

    }
  }
  export (type) {
    const json = {
      type: "FeatureCollection",
      name: "graphic",
      crs: {
        type: "name",
        properties: {
          name: "urn:ogc:def:crs:OGC:1.3:CRS84",
        },
      },
      features: [],
    };
    const managers = this.manager.values();
    for (let m of managers) {
      if (m.type === type) {
        json.features.push(m.toGeoJson());
      }
    }
    const blob = new Blob([JSON.stringify(json)], {
      type: "",
    });
    saveAs(blob, type + parseInt(Cesium.getTimestamp()) + ".geojson");
  }
  import(feat) {
    //地图初始化加载的时候有id就加上
    const id = !feat.id ? this.generateId() : feat.id;
    let graphic,
      coordinates,
      positions = [];
    if (feat.geometry.type.toUpperCase() === "LineString".toUpperCase()) {
      coordinates = feat.geometry.coordinates;
      for (let c of coordinates) {
        positions.push({
          lon: c[0],
          lat: c[1],
          height: c[2],
        });
      }
      try {
        graphic = CesiumPolyline.fromDegrees(
          this.viewer,
          positions,
          feat.properties
        );
      } catch (e) {
        console.log(e);
      }
    } else if (feat.geometry.type.toUpperCase() === "POLYGON") {
      coordinates = feat.geometry.coordinates[0];
      //由于导入的面编辑会少一根线，在这里补一下，尾部等于第一个点
      let first = coordinates[0];
      for (let c of coordinates) {
        positions.push({
          lon: c[0],
          lat: c[1],
          height: c[2],
        });
      }
      positions.push({
        lon: first[0],
        lat: first[1],
        height: first[2],
      });
      graphic = CesiumPolygon.fromDegrees(
        this.viewer,
        positions,
        feat.properties
      );
    } else {
      throw new Error("不能识别的数据源.");
    }
    if (graphic) {
      graphic.mid = id;
      graphic.mname = feat.properties.name;
      this.manager.set(id, graphic);
      const evt = new CustomEvent("addEvent", {
        detail: {
          mid: graphic.mid,
          mtype: graphic.mtype,
          mname: graphic.mname || "未命名",
        },
      });
      document.dispatchEvent(evt);
    }
    return graphic;
  }

  removeEventListener() {
    this.handler.removeInputAction(LEFT_CLICK);
    this.handler.removeInputAction(MOUSE_MOVE);
    this.handler.removeInputAction(RIGHT_CLICK);
    this.handler.removeInputAction(MOUSE_DOWN);
    this.handler.removeInputAction(MOUSE_UP);
  }
  removeAll() {
    const values = this.manager.values();
    for (let v of values) {
      //删除点
      if (v instanceof Array) {
        v.forEach((entity) => {
          this.viewer.entities.remove(entity);
        });
      } else {
        v.remove();
        v.destroy();
      }
    }
    this.manager.clear();
    this.tip.visible = false;
  }

  destroy() {
    this.activeManager = undefined;
    this.manager = undefined;
    this.editManager = undefined;
    this.removeEventListener();
    if (!this.handler.isDestroyed) {
      this.handler.destroy();
      this.handler = undefined;
    }
  }
  destroyManager() {
    const manager = this.editManager;
    const evt = new CustomEvent("destroyEvent", {
      detail: {
        mid: manager ? manager.mid : undefined,
      },
    });
    if (manager) {
      if (this.mode === "edit") {
        manager && manager.stopEdit();
      } else {
        manager && manager.destroy();
        this.manager.delete(this.graphicId);
      }
      //清除点
      this.clearEntity()
      this.editManager = undefined;
    }

    this.graphicId = undefined;
    this.handler.removeInputAction(MOUSE_MOVE);

    document.dispatchEvent(evt);
  }
  clearEntity(id = this.graphicId) {
    const entityArr = this.manager.get(id + "__entitys__")
    let self = this
    if (entityArr && entityArr.length) {
      entityArr.forEach((entity) => {
        self.viewer.entities.remove(entity);
      });
    }
  }
  visibleEntity(id = this.graphicId, status) {
    const entityArr = this.manager.get(id + "__entitys__")
    if (entityArr && entityArr.length) {
      entityArr.forEach((entity) => {
        entity.show = status
      });
    }
  }
}
export default GraphicManager;
